package com.karry.yl.service.financial.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.karry.commons.Constants;
import com.karry.commons.vo.LayTableResponse;
import com.karry.yl.dao.financial.SettlementMapper;
import com.karry.yl.domain.dto.JieSuanDto;
import com.karry.yl.domain.elder.Elderly;
import com.karry.yl.domain.financial.Receipt;
import com.karry.yl.domain.financial.SettlementRecords;
import com.karry.yl.service.elder.ElderlyService;
import com.karry.yl.service.financial.ReceiptService;
import com.karry.yl.service.financial.SettlementRecordsService;
import com.karry.yl.service.financial.SettlementService;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.ponly.payment.util.MD5;
import org.ponly.payment.util.SignUtils;
import org.ponly.payment.util.XmlUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class SettlementServiceImpl implements SettlementService {
    private static final Logger log = LoggerFactory.getLogger(ReceiptServiceImpl.class);
    @Autowired
    private SettlementMapper settlementMapper;
    @Autowired
    private SettlementRecordsService settlementRecordsService;
    @Autowired
    private ReceiptService receiptService;
    @Autowired
    private ElderlyService elderlyService;
    @Override
    public LayTableResponse selectJieSuanPage(int page, int limit,String elderlyName,Integer status,Long orgId) {
        Long count = settlementMapper.count(orgId);
        List<JieSuanDto> jieSuanList = new ArrayList<>();
        if(count > 0 ){
            jieSuanList = settlementMapper.selectJieSuanList(page -1,limit,elderlyName,status,orgId);
        }
        return new LayTableResponse(jieSuanList,count);
    }

    @Override
    @Transactional
    public void payByCash(Long elderlyId,BigDecimal settleAmount,Date settleTime, Long orgId,Date curr,String elderlyIdNo,String toll) {
        //将该老人在该机构的所有欠费账单设置为已支付
        StringBuilder rIds = new StringBuilder();
        String elderlyName = null;
        List<Receipt> receipts = receiptService.selectList(new EntityWrapper<Receipt>().eq("elderlyId", elderlyId).eq("orgId", orgId).eq("deleted", false).eq("status",Receipt.STATUS_ZC).le("createdTime",curr));
        for(Receipt r: receipts){
            r.setStatus(Receipt.STATUS_YZF);
            r.setRealAmount(r.getAmount());
            r.setPaymentMethod(Receipt.PM_XJ);
            r.setPaymentTime(new Date());
            receiptService.updateById(r);
            rIds.append("," + r.getId());
            if(null == elderlyName){
                elderlyName = r.getElderlyName();
            }
        }
        // 将本次收费计入结算记录
        SettlementRecords settlementRecords = new SettlementRecords();
        settlementRecords.setElderlyId(elderlyId);
        settlementRecords.setElderlyName(elderlyName);
        settlementRecords.setElderlyIdNo(elderlyIdNo);
        settlementRecords.setOrgId(orgId);
        settlementRecords.setSettleAmount(settleAmount);
        settlementRecords.setToll(toll);
        String receiptIds = rIds.toString();
        settlementRecords.setReceiptIds(receiptIds.isEmpty() ? null : receiptIds.substring(1));
        settlementRecords.setSettleTime(settleTime);
        settlementRecordsService.insert(settlementRecords);

    }

    @Override
    @Transactional
    public void updateReceipt(Long elderlyId, Date curr) {
        Elderly elderly = elderlyService.selectById(elderlyId);
        //将该老人在该机构的所有欠费账单设置为已支付
        List<Receipt> receipts = receiptService.selectList(new EntityWrapper<Receipt>().eq("elderlyId", elderlyId).eq("orgId", elderly.getOrgId()).eq("deleted", false).eq("status",Receipt.STATUS_ZC).le("createdTime",curr));
        StringBuilder rIds = new StringBuilder();
        for(Receipt r: receipts){
            r.setStatus(Receipt.STATUS_YZF);
            r.setRealAmount(r.getAmount());
            r.setPaymentMethod(Receipt.PM_XJ);
            r.setPaymentTime(new Date());
            receiptService.updateById(r);
            rIds.append("," + r.getId());
        }
        // 将本次收费计入结算记录
        SettlementRecords settlementRecords = new SettlementRecords();
        settlementRecords.setElderlyId(elderlyId);
        settlementRecords.setElderlyName(elderly.getName());
        settlementRecords.setElderlyIdNo(elderly.getIdNo());
        settlementRecords.setOrgId(elderly.getOrgId());
        settlementRecords.setSettleAmount(new BigDecimal(0));
        String receiptIds = rIds.toString();
        settlementRecords.setReceiptIds(receiptIds.isEmpty() ? null : receiptIds.substring(1));
        settlementRecords.setSettleTime(curr);
        settlementRecordsService.insert(settlementRecords);
    }

    @Override
    public boolean isPaid(Long elderlyId, Date curr) {
        Elderly elderly = elderlyService.selectById(elderlyId);
        //将该老人在该机构的所有欠费账单设置为已支付
        List<Receipt> receipts = receiptService.selectList(new EntityWrapper<Receipt>().eq("elderlyId", elderlyId).eq("orgId", elderly.getOrgId()).eq("deleted", false).eq("status",Receipt.STATUS_ZC).le("createdTime",curr));
        return receipts.size() > 0;
    }

    public Map<String, String> pay(Map<String, String> paramsMap) {
        paramsMap.put("notify_url", "https://www.kerry365.com/settlement/pay/notify");
        paramsMap.put("version", Constants.wft_version);
        paramsMap.put("charset", Constants.wft_charset);
        paramsMap.put("sign_type", Constants.wft_sign_type);
        paramsMap.put("mch_create_ip",Constants.IP);
        paramsMap.put("nonce_str", String.valueOf(new Date().getTime()));
        Map<String, String> params = SignUtils.paraFilter(paramsMap);
        StringBuilder buf = new StringBuilder((params.size() + 1) * 10);
        SignUtils.buildPayParams(buf, params, false);
        String preStr = buf.toString();
        String sign = MD5.sign(preStr, "&key=" + paramsMap.get("key"), "utf-8");
        paramsMap.put("sign", sign);
        String reqUrl = Constants.wft_req_url;
        CloseableHttpResponse response = null;
        CloseableHttpClient client = null;
        Map<String, String> resultMap = null;
        try {
            HttpPost httpPost = new HttpPost(reqUrl);
            StringEntity entityParams = new StringEntity(XmlUtils.parseXML(paramsMap), "utf-8");
            httpPost.setEntity(entityParams);
            httpPost.setHeader("Content-Type", "text/xml;utf-8");
            client = HttpClients.createDefault();
            response = client.execute(httpPost);
            if(response != null && response.getEntity() != null){
                resultMap = XmlUtils.toMap(EntityUtils.toByteArray(response.getEntity()), "utf-8");
                if(resultMap.containsKey("sign") && !SignUtils.checkParam(resultMap,  paramsMap.get("key"))){
                    log.error("验证签名不通过");
                    resultMap = null;
                }
            }
        } catch (Exception e) {
            log.error("操作失败，原因：",e);
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultMap;
    }
}
